home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / NDIR.C < prev    next >
C/C++ Source or Header  |  1991-11-21  |  7KB  |  218 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    n d i r . c                                                     */
  3. /*                                                                    */
  4. /*    Berkeley-style directory reading routine on MS-DOS by Samuel    */
  5. /*    Lam <skl@van-bc.UUCP>, June/87                                  */
  6. /*                                                                    */
  7. /*    Changes Copyright (c) 1990, 1991 by Andrew H. Derbyshire        */
  8. /*--------------------------------------------------------------------*/
  9.  
  10. /*--------------------------------------------------------------------*/
  11. /*                   Standard library include files                   */
  12. /*--------------------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include <string.h>
  17. #include <dos.h>
  18. #include <stdlib.h>
  19.  
  20. /*--------------------------------------------------------------------*/
  21. /*                    UUPC/extended include files                     */
  22. /*--------------------------------------------------------------------*/
  23.  
  24. #include "lib.h"
  25. #include "ndir.h"
  26.  
  27. #ifndef __TURBOC__
  28. void setdta( char far *dtaptr );
  29. char far *getdta( void );
  30. #endif
  31.  
  32. /*--------------------------------------------------------------------*/
  33. /*                          Global variables                          */
  34. /*--------------------------------------------------------------------*/
  35.  
  36. currentfile();
  37.  
  38. /*--------------------------------------------------------------------*/
  39. /*    o p e n d i r x                                                 */
  40. /*                                                                    */
  41. /*    Open a directory                                                */
  42. /*--------------------------------------------------------------------*/
  43.  
  44. extern DIR *opendirx( char *dirname, char *pattern)
  45. {
  46.    union REGS inregs, outregs;
  47.    struct SREGS segregs;
  48.    char pathname[128];
  49.    DTA far *dtasave;
  50.    DTA far *dtaptr;
  51.    char far *pathptr;
  52.    DIR *dirp;
  53.  
  54. /*--------------------------------------------------------------------*/
  55. /*                    Build pathname to be scanned                    */
  56. /*--------------------------------------------------------------------*/
  57.  
  58.    strcpy(pathname, dirname);
  59.    if ((*pattern != '/') || (dirname[ strlen(dirname) - 1] != '/'))
  60.       strcat(pathname,"/");
  61.    strcat(pathname, pattern);
  62.  
  63.    /* allocate control block */
  64.    dirp = malloc(sizeof(DIR));
  65.  
  66. /*--------------------------------------------------------------------*/
  67. /*                     Set disk transfer address                      */
  68. /*--------------------------------------------------------------------*/
  69.  
  70.    dtasave = (DTA far *)getdta();
  71.    dtaptr = (DTA far *)&(dirp->dirdta);
  72.    setdta((char far *)dtaptr);
  73.  
  74. /*--------------------------------------------------------------------*/
  75. /*                      look for the first file                       */
  76. /*--------------------------------------------------------------------*/
  77.  
  78.    inregs.h.ah = 0x4e;
  79.    pathptr = (char far *)pathname;
  80.    segregs.ds = FP_SEG(pathptr);
  81.    inregs.x.dx = FP_OFF(pathptr);
  82.    inregs.x.cx = 0;   /* attribute */
  83.    intdosx(&inregs, &outregs, &segregs);
  84.  
  85.    /* bad directory name? */
  86.    if (outregs.x.cflag && (outregs.x.ax == 2 || outregs.x.ax == 3)) {
  87.       free(dirp);
  88.       return NULL;
  89.    }
  90.  
  91.    dirp->dirfirst = outregs.x.cflag ? outregs.x.ax : 0;
  92.  
  93.    setdta((char far *)dtasave);
  94.    strcpy(dirp->dirid, "DIR");
  95.  
  96.    return dirp;
  97.  
  98. } /*opendir*/
  99.  
  100.  
  101. /*--------------------------------------------------------------------*/
  102. /*    r e a d d i r                                                   */
  103. /*                                                                    */
  104. /*    Get next entry in a directory                                   */
  105. /*--------------------------------------------------------------------*/
  106.  
  107. struct direct *readdir(DIR *dirp)
  108. {
  109.    int errcode;
  110.  
  111.    if (!equal(dirp->dirid, "DIR"))
  112.    {
  113.       printmsg(0,"Unexpected readdir call; no search in progress");
  114.       panic();
  115.    }
  116.  
  117.    if (dirp->dirfirst == -1) {
  118.       union REGS inregs, outregs;
  119.       struct SREGS segregs;
  120.       DTA far *dtaptr;
  121.       DTA far *dtasave;
  122.  
  123.      /* set DTA address to our buffer each time we're called */
  124.       dtasave = (DTA far *)getdta();
  125.       dtaptr = (DTA far *)&(dirp->dirdta);
  126.       setdta((char far *)dtaptr);
  127.  
  128.       inregs.h.ah = 0x4f;
  129.       segregs.ds = FP_SEG(dtaptr);
  130.       inregs.x.dx = FP_OFF(dtaptr);
  131.       intdosx(&inregs, &outregs, &segregs);
  132.       errcode = outregs.x.cflag ? outregs.x.ax : 0;
  133.  
  134.       setdta((char far *)dtasave);  /* Restore DTA address     */
  135.  
  136.    } else {
  137.  
  138.       errcode = dirp->dirfirst;
  139.       dirp->dirfirst = -1;
  140.  
  141.    };
  142.  
  143.    /* no more files in directory? */
  144.    if (errcode == 18)
  145.       return NULL;
  146.  
  147.    if ( errcode != 0)
  148.    {
  149.       errno = errcode;
  150.       printerr( "readdir" );
  151.       panic();
  152.    }
  153.  
  154.    dirp->dirent.d_ino = -1;   /* no inode information */
  155.    strlwr(strcpy(dirp->dirent.d_name, dirp->dirdta.filename));
  156.    dirp->dirent.d_namlen = strlen(dirp->dirent.d_name);
  157.    dirp->dirent.d_reclen = sizeof(struct direct) - (MAXNAMLEN + 1) +
  158.       ((((dirp->dirent.d_namlen + 1) + 3) / 4) * 4);
  159.  
  160.    return &(dirp->dirent);
  161.  
  162. } /*readdir*/
  163.  
  164. /*--------------------------------------------------------------------*/
  165. /*    c l o s e d i r                                                 */
  166. /*                                                                    */
  167. /*    Close a directory                                               */
  168. /*--------------------------------------------------------------------*/
  169.  
  170. void closedir(DIR *dirp)
  171. {
  172.  
  173.    strcpy(dirp->dirid, "XXX");
  174.    free(dirp);
  175.  
  176. } /*closedir*/
  177.  
  178. /*--------------------------------------------------------------------*/
  179. /*    s e t d t a                                                     */
  180. /*                                                                    */
  181. /*    Set disk transfer address.                                      */
  182. /*--------------------------------------------------------------------*/
  183.  
  184. #ifndef __TURBOC__
  185. void setdta( char far *dtaptr )
  186. {
  187.    union REGS inregs, outregs;
  188.    struct SREGS segregs;
  189.  
  190.    /* set DTA address to our buffer */
  191.    inregs.h.ah = 0x1a;
  192.    segregs.ds = FP_SEG(dtaptr);
  193.    inregs.x.dx = FP_OFF(dtaptr);
  194.    intdosx(&inregs, &outregs, &segregs);
  195. } /* setdta */
  196.  
  197. /*--------------------------------------------------------------------*/
  198. /*    g e t d t a                                                     */
  199. /*                                                                    */
  200. /*    Get disk transfer address.                                      */
  201. /*--------------------------------------------------------------------*/
  202.  
  203. char far *getdta( void )
  204. {
  205.    union REGS inregs, outregs;
  206.    struct SREGS segregs;
  207.    char far *result;
  208.  
  209.    inregs.h.ah = 0x2f;
  210.    intdosx(&inregs, &outregs, &segregs);
  211.    segread( &segregs );       /* Not sure they did not already update
  212.                                  ES after call ...                   */
  213.    result = (char far *) ((segregs.es << 16) || inregs.x.bx);
  214.    return result;
  215. } /* setdta */
  216.  
  217. #endif
  218.